home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / VIVIDUS / QD3D.SIT / qd3d / hedra.c < prev    next >
Text File  |  1991-10-09  |  6KB  |  280 lines

  1. /*    ======================================================================
  2.  
  3.     Cqd3dPort primitive three dimensional routine library.
  4.     
  5.     This is part of the qd3d Vividus Source Code Library.  See the
  6.     extern qd3d.doc documentation file for usage.  See individual
  7.     routines for routine documentation.
  8.     
  9.     Copyright 1991 by Vividus Consulting.
  10.     
  11.     This is not public domain source code.  You may not copy and
  12.     paste from this source code.  Read your Vividus Licensing
  13.     agreement for details and other restrictions.
  14.  
  15.     Note:    At present, HedraIntersect is not supported.
  16.     
  17.     ======================================================================    */
  18.  
  19. #include    <Cqd3dPort.h>
  20. #include    <geometry.h>
  21. #include    "hedra.h"
  22. #include    <math.h>
  23.  
  24. #define    abs(n)    ((n < 0) ? -n : n)
  25. #define    min(a,b)    ((a < b) ? a : b)
  26. #define    max(a,b)    ((a > b) ? a : b)
  27.  
  28. extern    Cqd3dPort    *the3dPort;
  29.  
  30. static    int            hedraVN = 0;
  31. static    vector        *hedraVerts = NULL;
  32. static    FixedVector    *hedraVFdc = NULL;
  33.  
  34. static    int            hedraCN = 0;
  35. static    int            hedraCL = 0;
  36. static    int            *hedraConn = NULL;
  37. static    int            *hedraCWrk = NULL;
  38.  
  39. /*    ======================================================================
  40.  
  41.     Usage:    Use HedraConn and HedraVerts to set the current hedra.  For
  42.             data format and general discussion see qd3d.doc.
  43.     
  44.     Note:
  45.         This is library is not optimized to take advantage of hedraVFdc
  46.         or hedraCWrk.  Use of those variables as intended will make this
  47.         library MUCH faster
  48.         
  49.     ======================================================================    */
  50.     
  51. void
  52. HedraVerts(int n, vector wc[], FixedVector fdc[])
  53. /*
  54.     Identifes the n vertices in wc (WC) to be used is subsequent calls to
  55.     hedra.  Fdc is client supplied workspace for the n vertices.  Fdc must
  56.     not be tampered with after the initial HedraVerts call.
  57. */
  58. {
  59.     hedraVN = n;
  60.     hedraVerts = wc;
  61.     hedraVFdc = fdc;
  62. }
  63.  
  64. void
  65. HedraConn(int faces, int connLen, int connArray[], int connWrk[])
  66. /*
  67.     Identifies the connArray (connectivity array) of length connLen and
  68.     faces for the subsequent hedra operations.  connWrk is client supplied
  69.     workspace of length connLen.
  70. */
  71. {
  72.     hedraCN = faces;
  73.     hedraCL = connLen;
  74.     hedraConn = connArray;
  75.     hedraCWrk = connWrk;
  76. }
  77.  
  78. void
  79. HedraFrame(void)
  80. /*
  81.     Frames the n polygons of the current hedra.  The framing color and
  82.     mode is the current foreground color and mode.
  83. */
  84. {
  85.     int        i;
  86.     vector    verts[PolyMaxN];
  87.     int        *q = hedraConn;
  88.     int        v, oldq;
  89.     int        j;
  90.     
  91.     for (i = 0; i < hedraCN; i++) {
  92.         j = 0;
  93.         do {
  94.             v = abs (*q);
  95.             vcopy(&hedraVerts[v], &verts[j]);
  96.             j++;
  97.             oldq = *q++;
  98.         } while (oldq >= 0);
  99.         Poly3dFrame(j, verts);
  100.     }        
  101. }
  102.  
  103. void
  104. HedraFrameErase(void)
  105. /*
  106.     Erases the Frames of the n polygons of the current hedra
  107. */
  108. {
  109.     int        i;
  110.     vector    verts[PolyMaxN];
  111.     int        *q = hedraConn;
  112.     int        v, oldq;
  113.     int        j;
  114.     
  115.     for (i = 0; i < hedraCN; i++) {
  116.         j = 0;
  117.         do {
  118.             v = abs (*q);
  119.             vcopy(&hedraVerts[v], &verts[j]);
  120.             j++;
  121.             oldq = *q++;
  122.         } while (oldq >= 0);
  123.         Poly3dFrameErase(j, verts);
  124.     }        
  125. }
  126.  
  127. void
  128. HedraFill(
  129.     void    (*color)(int face, vector *WCNorm)
  130. )
  131. /*
  132.     Fills and colors the polygons identified by the current hedra.
  133.     
  134.     Color() is a user supplied coloring function.  For each polygon identified in
  135.     the connectivity array, color() is called with the index of the face to be
  136.     colored and the normal of that face.  It must set the pencolor to the
  137.     appropriate color.
  138. */
  139. {
  140.     int        i;
  141.     vector    verts[PolyMaxN];
  142.     int        *q = hedraConn;
  143.     int        v, oldq;
  144.     int        j;
  145.     
  146.     vector    facetColor;
  147.     vector    norm;
  148.     
  149.     for (i = 0; i < hedraCN; i++) {
  150.         j = 0;
  151.         do {
  152.             v = abs (*q);
  153.             vcopy(&hedraVerts[v], &verts[j]);
  154.             j++;
  155.             oldq = *q++;
  156.         } while (oldq >= 0);
  157.         
  158.         vnorm(verts, &norm);
  159.         (*color) (i, &norm);
  160.         Poly3dFill(j, verts);
  161.     }        
  162.     
  163. }
  164.  
  165. void
  166. HedraErase(void)
  167. /*
  168.     Erases the polygons identified by the current hedra.
  169. */
  170. {
  171.     int        i;
  172.     vector    verts[PolyMaxN];
  173.     int        *q = hedraConn;
  174.     int        v, oldq;
  175.     int        j;
  176.     
  177.     for (i = 0; i < hedraCN; i++) {
  178.         j = 0;
  179.         do {
  180.             v = abs (*q);
  181.             vcopy(&hedraVerts[v], &verts[j]);
  182.             j++;
  183.             oldq = *q++;
  184.         } while (oldq >= 0);
  185.         
  186.         Poly3dErase(j, verts);
  187.     }        
  188.     
  189. }
  190.  
  191. Boolean
  192. HedraIntersect(
  193.     Ray        *r, 
  194.     double    *t,
  195.     int        *face,
  196.     vector    *faceNormal,
  197.     vector    *facePt
  198. )
  199. /*
  200.     HedraIntersect returns true if the indicated ray intersects
  201.     the current hedra.  If it does intersect, the ray parameter
  202.     t, the face index, faceNormal, and facePt parameters are
  203.     appropriately set.
  204.     
  205.     If the ray intersects the hedra in multiple locations, only the
  206.     closest intersection will be returned.
  207.     
  208.     NOTE:    At present, this routine is unsupported.
  209. */
  210. {
  211.     int        i;
  212.     vector    verts[PolyMaxN];
  213.     int        *q = hedraConn;
  214.     int        v, oldq;
  215.     int        j;
  216.     Plane    p;
  217.     
  218.     vector    xPoint, xNorm, tPoint;
  219.     int        xFace;
  220.     double    t1 = -1.0,
  221.             t2 = -1.0;
  222.     
  223.     for (i = 0; i < hedraCN; i++) {            /*    Have to test every face.    */
  224.         j = 0;
  225.         do {
  226.             v = abs (*q);
  227.             vcopy(&hedraVerts[v], &verts[j]);
  228.             j++;
  229.             oldq = *q++;
  230.         } while (oldq >= 0);
  231.  
  232.         vnorm(verts, &p.normal);
  233.         vcopy(&verts[0], &p.pt);
  234.         if (RayXPlane(r, &p, &t2, &tPoint)) {
  235.             if (PtInPoly(&tPoint, j, verts, &p.normal))
  236.                 if ((t2 > t1) || (t1 < 0.0)) {
  237.                     t1 = t2;
  238.                     xFace = i;
  239.                     vcopy(&p.normal, &xNorm);
  240.                     vcopy(&tPoint, &xPoint);
  241.                 }
  242.         }
  243.     }
  244.     
  245.     if (t1 > 0.000001) {
  246.         *t = t1;
  247.         *face = xFace;
  248.         vcopy(&xNorm, faceNormal);
  249.         vcopy(&xPoint, facePt);
  250.         return (true);
  251.     } else
  252.         return(false);
  253. }
  254.  
  255. void    Hedra2dBBox(Rect *r)
  256. /*
  257.     This routine returns the 2d quickdraw rectangle bounding the current
  258.     hedra.
  259.     
  260.     Note:    The returned rectangle doesn't consider pen width.
  261. */
  262. {
  263.     long    i;
  264.     Point    pt;
  265.     vector    p;
  266.     
  267.     TransformProject(1, &hedraVerts[0], &p);
  268.     pt.h = p.x;
  269.     pt.v = p.y;
  270.     SetRect(r, pt.h, pt.v, pt.h, pt.v);
  271.     for (i = 1; i < hedraVN; i++) {
  272.         TransformProject(1, &hedraVerts[i], &p);
  273.         pt.h = p.x;
  274.         pt.v = p.y;
  275.         r->top = min(r->top, pt.v);
  276.         r->left = min(r->left, pt.h);
  277.         r->right = max(r->right, pt.h);
  278.         r->bottom = max(r->bottom, pt.v);
  279.     }
  280. }